"""
Google Gemini LLM提供商实现
支持Gemini API
"""
from typing import Dict, Any, List
from loguru import logger

from storyforge.providers.base import ProviderBase
from storyforge.utils import HTTPClient


class LLMGeminiProvider(ProviderBase):
    """Gemini LLM提供商"""
    
    def __init__(self, config: Dict[str, Any]):
        """
        初始化Gemini提供商
        
        Args:
            config: 配置字典
        """
        super().__init__(config)
        
        # 从全局配置获取默认值
        from storyforge.config import get_config
        global_config = get_config()
        llm_config = global_config.llm
        
        self.api_key = config.get("apiKey")
        self.model = config.get("model", "gemini-pro")
        
        # 处理 base_url
        self.base_url = config.get("base_url") or config.get("endpoint") or "https://generativelanguage.googleapis.com/v1beta/models"
        
        # 从提供商配置或全局llm配置读取参数
        self.timeout = config.get("timeout") or llm_config.requestTimeout
        self.max_retries = config.get("maxRetries") or llm_config.maxRetries
        self.default_temperature = config.get("temperature") or llm_config.defaultTemperature
        self.default_max_tokens = config.get("maxOutputTokens") or llm_config.defaultMaxTokens
        
        # 初始化HTTP客户端
        proxy_config = self._build_proxy_config(config)
        http_config = {
            "proxy": proxy_config,
            "timeout": self.timeout
        }
        self.http_client = HTTPClient(http_config)
        
        if not self.api_key:
            raise ValueError("Gemini API密钥未配置")
    
    def _build_proxy_config(self, config: Dict[str, Any]):
        """
        构建代理配置（优先使用提供商级别，否则使用全局配置）
        
        Args:
            config: 提供商配置字典
            
        Returns:
            代理配置字典，格式: {"http": "http://proxy:port", "https": "https://proxy:port"}，未配置返回None
        """
        from storyforge.config import get_config
        
        # 优先使用提供商级别的代理配置
        proxy_config = config.get("proxy")
        if proxy_config:
            return proxy_config
        
        # 使用全局代理配置
        global_config = get_config()
        if global_config.proxy:
            return {
                "http": global_config.proxy.http,
                "https": global_config.proxy.https
            }
        
        return None
    
    def name(self) -> str:
        """返回提供商名称"""
        return "gemini"
    
    def generate(
        self,
        messages: List[Dict[str, str]],
        temperature: float = None,
        max_tokens: int = None,
        **kwargs
    ) -> str:
        """
        生成文本
        
        Args:
            messages: 消息列表
            temperature: 温度参数（None则使用默认值）
            max_tokens: 最大token数（None则使用默认值）
            **kwargs: 其他参数
            
        Returns:
            生成的文本
        """
        # 转换消息格式
        contents = []
        for msg in messages:
            role = "user" if msg["role"] in ["user", "system"] else "model"
            contents.append({
                "role": role,
                "parts": [{"text": msg["content"]}]
            })
        
        # 构建完整URL
        # Gemini的URL结构比较特殊，base_url通常指向models
        # 如果base_url以/models结尾，则直接拼接
        # 否则假设base_url是根路径
        if self.base_url.endswith("/models"):
            url = f"{self.base_url}/{self.model}:generateContent?key={self.api_key}"
        else:
            url = f"{self.base_url}/models/{self.model}:generateContent?key={self.api_key}"
        
        # 构建请求体
        payload = {
            "contents": contents,
            "generationConfig": {
                "temperature": temperature if temperature is not None else self.default_temperature,
                "maxOutputTokens": max_tokens if max_tokens is not None else self.default_max_tokens,
            }
        }
        
        try:
            logger.debug(f"调用Gemini API: {self.model}")
            response = self.http_client.post(
                url,
                json_data=payload,
                timeout=self.timeout
            )
            
            if response.status_code != 200:
                error_msg = f"Gemini API错误 {response.status_code}: {response.text}"
                logger.error(error_msg)
                raise Exception(error_msg)
            
            result = response.json()
            
            # 提取生成的文本
            if "candidates" in result and len(result["candidates"]) > 0:
                candidate = result["candidates"][0]
                if "content" in candidate and "parts" in candidate["content"]:
                    parts = candidate["content"]["parts"]
                    if parts and len(parts) > 0:
                        content = parts[0].get("text", "")
                        logger.debug(f"Gemini返回: {len(content)} 字符")
                        return content
            
            raise Exception(f"Gemini响应格式错误: {result}")
            
        except Exception as e:
            logger.error(f"Gemini生成失败: {e}")
            raise
    
    def submit(self, payload: Dict[str, Any]) -> str:
        """提交任务（同步调用）"""
        messages = payload.get("messages", [])
        temperature = payload.get("temperature", 0.7)
        max_tokens = payload.get("max_tokens", 2000)
        
        result = self.generate(messages, temperature, max_tokens, **payload)
        return result
    
    def poll(self, external_job_id: str) -> Dict[str, Any]:
        """轮询任务状态（同步调用，直接返回结果）"""
        return {
            "status": "succeeded",
            "result": external_job_id
        }
